애플릿 Applet :: AWT스윙GUI[SSISO Community]
 
SSISO 카페 SSISO Source SSISO 구직 SSISO 쇼핑몰 SSISO 맛집
추천검색어 : JUnit   Log4j   ajax   spring   struts   struts-config.xml   Synchronized   책정보   Ajax 마스터하기   우측부분

AWT스윙GUI
탭으로 나뉘어져 있는 글입니다.   [1][2][3][4][5][6][7][8][9]
등록일:2008-03-17 18:12:35 (0%)
작성자:
제목:애플릿 Applet

Chapter

 19

Applet

 

애 플릿(Applet)은 패널(Panel)을 상속하는 클래스로 웹브라우저에 담겨서 실행되는 작은 응용프로그램을 말한다. 아마도 자바보다 애플릿이라는 말을 먼저 접해본 독자가 많을 것이다. 몇 년 전만 해도 HTML의 정적인 면을 보완해주는 도구인 애플릿은 상당한 인기를 누리고 있었다. 하지만 최근에 플래시와 같은 강력한 도구들이 나오면서 자바 애플릿의 부담이 줄었다고 할 수 있다. 그러나 자바의 애플릿은 다른 어떤 도구보다도 표현력이 뛰어나다.

 

웹 브라우저에서 애플릿 tag가 포함된 웹 문서를 열면 애플릿이 웹서버로부터 사용자 컴퓨터로 전송되고 정해진 절차에 따라 애플릿이 실행된다. 웹브라우저는 자체적으로 JVM을 가지고 있어서 JDK가 설치되어 있지 않아도 애플릿을 실행시킬 수 있다. 그러나 문제는 웹브라우저의 JVM 버전이 JDK의 버전보다 훨씬 낮다는 것과 웹브라우저마다 애플릿이 다르게 동작한다는 것이다. 현재 JDK1.4.x가 출시되었지만 웹브라우저는 JDK1.1.x 이하를 지원하기 때문에 JDK1.4.x로 애플릿을 만들면 JDK가 설치되어있지 않은 컴퓨터에서는 버전의 차이로 인해 애플릿이 제대로 실행되지 않는다. 이런 문제를 극복하는 수단으로 1.1.x의 JDK로 애플릿을 제작하거나 Java Plug-In을 설치하는 방법이 있다. Java Plug-in은 웹브라우저의 비호환성 문제와 버전의 차이를 극복하는 좋은 해결책이다. JDK를 설치했다면 자동으로 Java Plug-In이 설치되므로 따로 설치할 필요는 없다.

 

 

 

애플릿 만들기

Applet 클래스는 java.applet 패키지에 있는 클래스로 Panel을 상속한다. 애플릿도 컨테이너이므로 AWT 컴포넌트를 담을 수 있다. Applet 클래스는 애플릿만의 독특한 성질 때문에 Panel로부터 상속받은 멤버 외에도 많은 멤버를 가진다.

 

어떤 클래스가 애플릿이 되려면 어떻게 해야할까? 답은 상속에 있다. Frame을 상속하면 프레임이 되듯이 Applet을 상속하면 애플릿이 된다.

 

import java.applet.*;

public class MyApplet extends Applet{

  ...

}

 

MyApplet 클래스는 Applet을 상속하기 때문에 애플릿이다. 이제 할 일은 애플릿을 웹 페이지에 포함시킨 다음, 웹브라우저로 웹 페이지를 불러와 보는 것이다. 애플릿을 웹 페이지에 포함시키려면 애플릿과 관련된 HTML tag를 사용해야한다.

 

<Htm>

<Body>

 

      <Applet code="MyApplet.class" width="200" height="200">

      </Applet>

 

</Body>

</Htm>

 

HTML(Hypertext Markup Language)이란 웹 페이지(홈페이지)를 만드는 언어로 대부분의 웹 페이지가 HTML로 만들어진다. <Htm>과 같은 <?>을 태그(tag)라고 한다. 태그는 시작 태그와 끝 태그로 이루어져 있다. <Htm>의 끝 태그는 </Htm>이고 <Body>의 끝 태그는 </Body>이다. 위에서 진하게 표시된 것이 애플릿 태그인데 애플릿 태그는 <Applet>으로 시작하여 </Applet>으로 끝난다. 시작 태그 안의 code는 애플릿 클래스의 경로를 표시하고, width와 height는 웹 페이지에 보여지는 애플릿의 너비와 높이를 정하는 것이다. 웹 페이지를 저장하고 웹브라우저로 불러오면 애플릿이 실행되는 것을 확인할 수 있다.

 

실제로 애플릿을 만들어보자. 다음 소스를 코딩하여 컴파일 하자.

 

Applet1.java

 

import java.awt.*;

import java.applet.*;

public class Applet1 extends Applet{

  public void paint(Graphics g){

    this.setBackground(Color.red);

    g.drawString("애플릿의 세계로...",20,50);

  }

}


 

 

Applet1 클래스는 Applet을 상속했기 때문에 애플릿이다. 그런데 눈을 크게 뜨고 보아도 main 메소드가 없다. 애플릿은 응용 프로그램과는 달리 웹브라우저에서 실행된다는 특성 때문에 main 메소드가 필요 없다.

 

이제 웹 페이지를 다음과 같이 작성하고 'Applet1.htm'이라는 이름으로 저장하자.

 

Applet1.htm

 

<Htm>

<Body>

 

        <h1> 애플릿 만들기 </h1>

 

      <Applet code="Applet1.class" width=150 height=100>

      </Applet>

 

</Body>

</Htm>


 

웹브라우저로 'Applet1.htm'을 불러오면 그림과 같이 웹 페이지 안에 애플릿이 실행되는 것을 볼 수 있을 것이다.

 

[그림 19-1] 웹브라우저로 본 애플릿

 

클 래스와 웹 페이지를 정확하게 작성했는데도 애플릿이 실행되지 않으면 'Applet1.class'와 'Applet1.htm'이 같은 디렉토리에 있는지 확인하자. 간단한 애플릿을 만들고 웹브라우저에서 실행시켜보았다. 그러나 애플릿을 테스트해 보기 위해 일일이 웹브라우저로 확인하는 것은 많은 시간과 정력을 소모시킨다. 그러나 다행이 JDK는 웹브라우저의 도움 없이 애플릿을 실행시킬 수 있는 도구인 Applet Viewer를 제공한다. 애플릿 뷰어로 애플릿을 실행시키려면 다음과 같이 하면 된다.

 

appletviewer  Applet1.htm

 

다음 그림은 애플릿 뷰어로 실행한 화면이다. 애플릿 뷰어는 웹 페이지의 내용 중에서 애플릿만 보여준다.

[그림 19-2] 애플릿 뷰어

 


 

애플릿의 삶과 죽음

애 플릿은 웹브라우저에 담겨서 실행되기 때문에 동작 방식이 일반 응용프로그램과 다르다. 큰 차이중의 하나가 애플릿은 main 메소드가 필요 없다는 것이다. 대신에 애플릿에는 init, start, stop, 그리고 destroy 등의 메소드가 있다. 이들 메소드는 각자 정해진 시점에서 자동으로 호출된다.

 

 

Applet 클래스의 유용한 메소드

 

public void init()

애플릿의 초기화 작업을 수행하는 메소드

public void start()

애플릿을 실행할 필요가 있을 때 호출되는 메소드.

public void stop()

애플릿의 실행을 멈출 필요가 있을 때 호출되는 메소드.

public void destroy()

웹 브라우저가 종료될 때 호출된다.

 

그 러나 브라우저마다 이들 메소드의 호출 시점이 조금씩 다르다는 것이 문제가 된다. 인터넷 익스플로러5.x의 경우 애플릿 클래스가 메모리에 로드되면 애플릿 객체가 생기고 애플릿 객체의 init이 호출된다. 그 다음 start가 호출된다. 다시 말해 인터넷 익스플로러가 애플릿이 있는 웹 페이지를 불러오면 다음과 같은 순서로 애플릿이 실행된다.

 

애플릿 클래스의 로드 -> 애플릿 객체의 생성(생성자 호출) -> init -> start

 

애플릿이 실행되고 있는 웹 페이지에서 다른 웹 페이지로 이동하면 stop()이 호출된다. 따라서 애플릿의 실행을 멈추게 하는 코드를 stop 메소드에 삽입해야 한다.

 

다시 애플릿이 있는 본래의 웹 페이지로 돌아오면 다시 애플릿 객체가 생기고 init과 start가 차례대로 호출된다. 다시 말해 다음과 같다.

 

애플릿 객체의 생성(생성자 호출) -> init -> start

 

destroy는 웹브라우저를 닫으면 호출되는 메소드이다. 따라서 이 메소드 안에 애플릿이 사용한 자원을 반납하는 코드를 삽입해야 한다.

 

다음 예제는 애플릿의 여러 메소드들이 호출되는 시기를 알아보는 것이다.

 

Applet2.java

 

import java.awt.*;

import java.applet.*;

public class Applet2 extends Applet{

  // 메소드 호출 시기와 회수를 보여주기 위한 텍스트 영역

  TextArea ta=new TextArea();

  

  // 메소드의 호출 회수를 기억하기 위한 변수들

  static int objectCount, initCount, startCount, stopCount, destoryCount;

 

  static String info="";   // 메소드의 호출 순서와 회수를 보여주기 위한 String 객체

 

  public Applet2(){                      // 생성자

    setLayout(new BorderLayout());       // 애플릿 객체의 레이아웃

    add(ta);                             // 텍스트 영역을 추가한다.

    objectCount++;                      // 생성자의 호출 횟수를 기억한다.

    info+="객체 생성 횟수: "+objectCount+"\n";

    ta.setText(info);                      // 객체의 생성회수를 보여준다.

  }

  public void init(){               // 애플릿의 초기화 작업을 수행하는 메소드

    initCount++;                   // init 메소드의 호출 횟수를 기억한다.

    info+="init 호출 횟수: "+initCount+"\n";

    ta.setText(info);                // init 메소드의 호출 회수를 보여준다.

  }

  public void start(){             // 애플릿의 시작 메소드

    startCount++;

    info+="start 호출 횟수: "+startCount+"\n";

    ta.setText(info);

  }

  public void stop(){             // 애플릿의 중지 메소드

    stopCount++;

    info+="stop 호출 횟수: "+stopCount+"\n";

    ta.setText(info);

  }

  public void destory(){         // 애플릿 종료(브라우저 종료) 메소드

    destoryCount++;

    info+="destroy 호출 횟수: "+destoryCount+"\n";

    ta.setText(info);

  }

}


 

<Applet code="Applet2.class" width=200 height=200>

</Applet>

 

웹 페이지에 위 tag를 삽입하고 'Applet2.htm'으로 저장한 다음 인터넷 익스플로러나 넷스케이프와 같은 웹브라우저로 웹 페이지를 열어보자.

다음 그림은 인터넷 익스플로러에서 새로 고침을 눌렀을 때 실행된 화면이다.

[그림 19-3] 애플릿의 삶과 죽음

 

넷 스케이프에서 열어보면 인터넷 익스플로러와 다소 다르게 동작할 것이다. 브라우저들의 JVM이 서로 다르기 때문에 기인하는 것이다. 프로그래머는 인터넷 익스플로러와 넷스케이프 모두에서 잘 돌아가도록 프로그래밍 해야하는 부담이 있다. 호환성 문제는 브라우저를 만든 회사들이 적절한 선에서 타협해야 하지만 자사의 이익이 걸린 문제이므로 당장은 해결되기 어려울 것으로 본다.

 

 

애플릿의 미디어 처리

HTML 의 정적인 면을 보완한다는 목적에서 보듯이 애플릿은 이미지와 오디오를 보다 편리하게 처리할 수 있도록 해주는 메소드를 제공한다. 애플릿의 getImage 메소드는 Toolkit 객체를 얻지 않고도 이미지를 불러올 수 있게 한다. 그리고 play 메소드나 AudioClip객체를 이용하면 URL 상의 오디오 파일을 쉽게 연주할 수 있다. 물론 이미지나 오디오 파일을 URL로부터 다운로드 할 때 많은 시간이 걸린다. 따라서 파일을 압축하거나 백그라운드 쓰레드에서 이미지를 다운로드 하여 사용자의 기다리는 시간을 줄여야 할 것이다.

 

 

이미지 처리

애플릿도 AWT 컴포넌트이므로 이미지 처리 방식은 Java2D에서 했던 것처럼 하면 된다. 또한 이미지 객체를 쉽게 얻을 수 있는 getImage 메소드를 추가로 가지고 있어서 편리하다.

 

Applet 클래스의 이미지 관련 메소드

 

public Image getImage(URL url)

url에 해당하는 이미지 객체를 반환한다.

public Image getImage(URL url, String name)

url에 있는 name의 이름을 가진 이미지 객체를 반환한다.

 

애플릿은 클래스의 위치(code base)와 웹 페이지의 위치(document base)를 알 수 있는 메소드를 제공한다.

 

Applet 클래스의 위치 관련 메소드

 

public URL getCodeBase()

애플릿 코드(클래스)가 있는 위치의 url을 반환한다.

public URL getDocumentBase()

웹 페이지가 있는 위치의 url을 반환한다.

 

애플릿 클래스와 이미지파일이 같은 위치에 있다면 이미지파일을 불러올 때 아래와 같이 하면 된다.

 

Image img1= getImage(getCodeBase(), "이미지파일이름");

 

웹 페이지가 있는 위치의 하위 디렉토리로 images라는 디렉토리가 있을 때 images 디렉토리에 있는 이미지파일을 불러오려면 다음과 같이 할 수 있다.

 

Image img2= getImage(getDocumentBase(), "images/이미지파일이름");

 

애플릿 클래스와 웹 페이지가 같은 위치에 있다면 getCodeBase()와 getDocumentBase()는 같은 URL을 반환할 것이다.

 

다음 예제를 해보려면 이미지 파일이 "images" 디렉토리 안에 있어야 한다.

 

Applet3.java

 

import java.awt.*;

import java.applet.*;

public class Applet3 extends Applet{

  Image img1, img2, img3;

  public void init(){

    // 이미지 객체를 얻는다.

    img1=getImage(getDocumentBase(),"images/back1.gif");

    img2=getImage(getDocumentBase(),"images/back2.gif");

    img3=getImage(getDocumentBase(),"images/back3.gif");

  }

  public void paint(Graphics g){

    g.drawImage(img1, 0,50,this);

    g.drawImage(img2, 100,50,this);

    g.drawImage(img3, 200,50,this);

  }

}


 

<Applet code="Applet3.class" width=300 height=200>

</Applet>

 

 

 

오디오 처리

자 바에서 연주할 수 있는 파일은 AIFF, AU, WAV, MIDI, RMF 등으로 다양하다. applet 패키지에 있는 AudioClip 인터페이스는 오디오와 관련된 API로 오디오 파일을 반복하여 연주할 수도 있고 필요할 때 중지시킬 수도 있다.

 

AudioClip 인터페이스의 유용한 메소드

 

void play();

오디오 파일을 한번 연주한다.

void stop();

오디오 파일의 연주를 멈춘다.

void loop();

오디오 파일을 반복하여 연주한다.

 

오디오 파일을 연주하려면 애플릿 객체로부터 AudioClip 객체를 얻으면 된다.

 

 

Applet 클래스의 오디오 관련 메소드

 

public void play(URL url)

url에 해당하는 오디오 파일을 연주한다.

public void play(URL url, String name)

url에 있는 name의 이름을 가진 오디오 파일을 연주한다.

public final static AudioClip newAudioClip(URL url)

url에 해당하는 오디오 파일을 연주할 수 있는 AudioClip 객체를 반환한다.

public AudioClip getAudioClip(URL url)

public AudioClip getAudioClip(URL url, String name)

url에 해당하는 오디오 파일을 연주할 수 있는 AudioClip 객체를 반환한다.

 

newAudioClip 메소드는 static이기 때문에 애플릿 객체 없이 AudioClip 객체를 만들 수 있다. 따라서 이 메소드를 이용하면 애플릿뿐만 아니라 응용프로그램에서도 오디오를 연주할 수 있다.

 

AudioClip audio=Applet.newAudioClip(url);

 

다음 예제를 컴파일 하여 웹브라우저로 불러오면 애플릿이 시작되었을 때 해당 오디오 파일을 반복하여 연주할 것이다. 또 다른 웹 페이지로 이동하면 연주를 멈출 것이다.

 

Applet4.java

 

import java.awt.*;

import java.applet.*;

public class Applet4 extends Applet{

  AudioClip music;

  public void init(){

    // AudioClip 객체를 얻는다.

    music=getAudioClip(getCodeBase(),"sounds/spacemusic.au");

  }

  public void start(){      // 애플릿이 시작되면 호출된다.

    music.loop();        // 반복하여 연주한다.

  }

  public void stop(){      // 다른 웹 페이지로 이동하면 호출된다.

    music.stop();        // x1, 연주를 멈춘다.

  }

}


 

x1행의 music.stop()을 호출하지 않으면 다른 웹 페이지로 이동했을 때 연주를 멈추지 않고 웹브라우저가 종료하면 연주를 멈춘다.

 

 

애플릿 파라미터

애플릿은 웹 페이지의 <param> 태그로부터 문자열 정보를 얻을 수 있다. 웹 페이지에서 자주 사용되는 흐르는 문자열과 같은 애플릿을 만들 때 유용하다. 다른 웹 페이지에서는 다른 문자열을 사용할 수 있다.

 

다음과 같이 <param> 태그는 애플릿 태그 내부에 위치하며 name과 value를 지정하도록 되어 있다.

 

<Applet ...>

   <param name="변수이름" value="값">

    ...

</Applet>

 

name은 파라미터 변수의 이름이고 value는 변수에 대입되는 값을 의미한다. 애플릿에서 파라미터의 값을 읽어오려면 getParameter 메소드를 이용하면 된다.

 

String param=getParameter("변수이름");

// "변수이름"에 해당하는 파라미터의 value가 param에 대입된다.

 

실제로 흐르는 문자열 애플릿을 만들어 보자. 더블 버퍼링 기법을 이용하여 화면의 떨림을 제거했다.

 

Applet5.java

 

import java.awt.*;

import java.applet.*;

public class Applet5 extends Applet implements Runnable{

  Image background;             // 애플릿의 배경 그림

  String text;                     // 흐르는 문자열을 위한 변수

  boolean loop=true;             // 스레드를 위한 변수

  int delay;                      // 흐르는 문자열의 빠르기 조절을 위한 변수

 

  public void init(){             // 애플릿의 초기화

    // "background" 파라미터의 경로에 해당하는 이미지 객체를 얻는다.

    background=getImage(getCodeBase(), getParameter("background"));

 

    // "text" 파라미터의 값을 얻는다.

    text=getParameter("text");

 

    // "delay" 파라미터의 값을 얻어서 정수로 변환한다.

    delay=Integer.parseInt(getParameter("delay"));

  }

  public void start(){                // 애플릿이 시작되면 호출된다.

    Thread t;

    t=new Thread(this);              // 새로운 스레드를 만든다.

    t.start();                         // run 메소드를 호출한다.

  }

  public void stop(){              // 다른 웹 페이지로 이동하면 호출된다.

    loop=false;                     // 스레드를 멈추게 한다.

  }

  public void run(){

    int x=0;

    Graphics g=getGraphics();       // 애플릿의 그래픽 객체를 얻는다.

 

    // 애플릿의 크기와 같은 버퍼 이미지 생성

    Image buffer=createImage(getWidth(),getHeight());

    Graphics g2=buffer.getGraphics();   // 버퍼 이미지의 그래픽 객체를 얻는다.

 

    while(loop){                      // loop=false가 되면 스레드가 죽는다.

      // 버퍼에 배경그림을 그린다.

      g2.drawImage(background,0,0, getWidth(), getHeight(), this);

 

      // 버퍼의 (x, 50)에 text를 그린다.

      g2.drawString(text, x, 50);

      

      // 애플릿에 버퍼 이미지를 그린다.

      g.drawImage(buffer,0,0,this);

 

      x+=2;                     // x를 증가시킨다.

      if(x>=getWidth())x=0;      // x가 애플릿의 너비를 벗어나면 0으로 바꾼다.

      try{

        Thread.sleep(delay);    // delay 만큼 쉰다.

      }catch(Exception e){}

    }

  }

}


 

위 예제가 정상적으로 실행되려면 다음 코드를 포함하는 웹 페이지를("Applet5.htm")을 작성해야 한다.

 

<Applet code="Applet5.class" width=300 height=100>

     <param name="background" value="images/back2.gif">

     <param name="text" value="생각하는 애플릿 프로그래밍">

     <param name="delay" value="100">

</Applet>

 

아래 그림은 Applet Viewer로 실행된 화면이다.

[그림 19-4] 애플릿 파라미터 받기

 

delay에 큰 수를 대입하면 문자열이 상대적으로 천천히 움직일 것이다. 폰트를 다양하게 처리하고 싶다면 Font 클래스와 FontMetrics 클래스를 이용하자(API 참고).

 

 

브라우저에서 애플릿 제어하기

웹 페이지에 포함되는 애플릿에게 이름을 지어주면 브라우저에서 애플릿의 메소드를 호출할 수 있다. 애플릿의 이름은 <Applet> 태그 안의 name에 삽입한다.

 

<Applet code="애플릿클래스" name="이름" width=300 height=100 >

</Applet>

 

다음 애플릿은 paint 메소드가 호출되었을 때 문자열을 출력한다.

 

Applet6.java

 

import java.awt.*;

import java.applet.*;

public class Applet6 extends Applet{

  public void paint(Graphics g){

    g.drawString("브라우저에서 애플릿 메소드 호출",10,50);

  }

  public void setRed(){         // 애플릿의 배경색을 빨간색으로 설정한다.

    setBackground(new Color(255, 0, 0));

  }

  public void setGreen(){       // 애플릿의 배경색을 초록색으로 설정한다.

    setBackground(new Color(0, 255, 0));

  }

  public void setBlue(){         // 애플릿의 배경색을 파란색으로 설정한다.

    setBackground(new Color(0, 0, 255));

  }

}


 

웹 브라우저에서 애플릿의 메소드 setRed, setGreen, setBlue를 호출하여 애플릿의 배경색을 바꿀 수 있다. 아래는 위에서 만든 애플릿을 포함하는 웹 페이지의 소스이다.

 

Applet6.htm

 

<Htm>

<Body>

   <Center>

   <!-- 애플릿 태그를 삽입하고 애플릿의 이름을 applet로 정한다. -->

   <Applet code="Applet6.class" name="applet" width=300 height=100 >

   </Applet>

   <br>

   <!-- 버튼을 만든다. 버튼을 클릭 하면 애플릿의 메소드를 호출한다. -->

   <Input type="button" value="빨강" onclick="applet.setRed();">

   <Input type="button" value="초록" onclick="applet.setGreen();">

   <Input type="button" value="파랑" onclick="applet.setBlue();">

   </Center>

</Body>

</Htm>


 

[그림 19-5] 애플릿 제어하기

 

 

 

애플릿에서 브라우저 제어하기

브 라우저에서 애플릿을 제어할 수 있는 것처럼 애플릿에서도 브라우저를 제어할 수 있다. AppletContext 클래스는 애플릿을 포함한 브라우저와 애플릿 환경에 관련된 클래스이다. AppletContext를 이용하면 브라우저뿐만 아니라 같은 웹 페이지에 포함된 다른 애플릿까지 제어할 수 있다.

 

AppletContext 클래스의 유용한 메소드

 

void showDocument(URL url);

url에 해당하는 웹 페이지를 불러온다.

public void showDocument(URL url, String target);

url에 해당하는 웹 페이지를 target 프레임에 불러온다.

Applet getApplet(String name);

같은 웹 페이지 안에 있는 name이라는 이름을 가진 애플릿을 반환한다.

Enumeration getApplets();

같은 웹 페이지 안의 모든 애플릿을 반환한다.

void showStatus(String status);

웹브라우저의 상태 표시줄에 status 문자열을 보여준다.

 

애플릿의 getAppletContext 메소드를 호출하면 AppletContext 객체를 얻을 수 있다.

 

AppletContext context=getAppletContext();

 

롤오버 버튼 효과의 애플릿을 만들어 보자. 마우스가 애플릿 안으로 들어왔을 때의 이미지와 마우스가 애플릿 밖으로 나갔을 때의 이미지를 다르게 보여줄 것이다. 그리고 마우스를 누르면 다른 웹 페이지를 불러오게 할 것이다.

 

Applet7.java

 

import java.awt.*;

import java.applet.*;

import java.net.*;

import java.awt.event.*;

public class Applet7 extends Applet implements MouseListener{

  // 마우스가 애플릿 안으로 들어왔을 때 이미지와 나갔을 때 이미지

  Image image1, image2;

 

  URL url;                                // 웹브라우저로 불러올 페이지의 URL

  String target;                           // 대상 프레임

  AppletContext context;                 // AppletContext 객체를 위한 레퍼런스

 

  public void init(){

    target=getParameter("target");          // "target" 파라미터의 값을 얻는다.

    try{

      url=new URL(getParameter("url"));    // "url" 파라미터의 값을 얻는다.

    }catch(Exception e){}

 

    // 각각의 파라미터로부터 이미지 객체를 얻는다.

    image1=getImage(getDocumentBase(), getParameter("image1"));

    image2=getImage(getDocumentBase(), getParameter("image2"));

 

    context=getAppletContext();           // AppletContext 객체를 얻는다.

    addMouseListener(this);                 // 마우스 이벤트 처리

  }

  public void paint(Graphics g){

    g.drawImage(image1,0,0,getWidth(),getHeight(),this);    // image1을 그린다.

  }

 

  // 마우스가 애플릿 안으로 들어왔을 때 호출된다.

  public void mouseEntered(MouseEvent me){

    // image2를 그린다.

    getGraphics().drawImage(image2,0,0,getWidth(),getHeight(),null);

    context.showStatus("그림을 누르세요.");  // 상태 표시줄에 문자열을 보여준다.

  }

 

  // 마우스가 애플릿 밖으로 나갔을 때 호출된다.

  public void mouseExited(MouseEvent me){

    // image1을 그린다.

    getGraphics().drawImage(image1,0,0,getWidth(), getHeight(), null);

    context.showStatus("브라우저 제어하기.");

  }

  public void mouseClicked(MouseEvent me){         // 애플릿을 마우스로 누름

     // url에 해당하는 웹 페이지를 target 프레임에 불러온다.

    context.showDocument(url, target);

  }

  public void mousePressed(MouseEvent me){}

  public void mouseReleased(MouseEvent me){}

}


 

Applet7.htm

 

<Htm>

<Body>

   <Center>

   <Applet code="Applet7.class" name="applet7" width=112 height=30 >

     <param name="target" value="_blank">

     <param name="url" value="http://java.pukyung.co.kr">

     <param name="image1" value="images/logoOut.gif">

     <param name="image2" value="images/logoIn.gif">

   </Applet>

   </Center>

</Body>

</Htm>


 

[그림 19-6] 웹브라우저 제어하기



 

다른 애플릿 제어하기

AppletContext의 getApplet, getApplets 메소드를 이용하면 같은 웹 페이지에 있는 다른 애플릿을 제어할 수 있다.

예 를 들어 두 애플릿(Applet8, Applet8_Controller)이 같은 웹 페이지에서 불려진다고 생각하자. 이때 Applet8.class의 이름을 applet8이라고 정하자. 아래는 두 애플릿을 불러오는 HTML 태그이다.

 

<Applet code="Applet8.class" name="applet8" width=200 height=200 ></Applet>

 

<Applet code="Applet8_Controller.class" width=200 height=200 ></Applet>

 

Applet8_Controller 에서 Applet8을 제어하려면 Applet8_Controller의 AppletContext 객체를 얻은 다음에 getApplet 메소드로 Applet8의 객체를 얻어와야 한다. 그리고 getApplet은 Applet형 객체를 반환하기 때문에 Applet8로 형 변환해야 할 것이다.

 

// AppletContext 객체를 얻는다.

AppletContext context=getAppletContext();

 

// 같은 웹페이지의 "applet8"이라는 이름을 가지는 애플릿 객체를 얻는다.

Applet8 applet=(Applet8)context.getApplet("applet8");

 

실제로 두 애플릿을 정의해 보자. Applet8 클래스는 다음과 같다.

 

Applet8.java

 

import java.awt.*;

import java.applet.*;

public class Applet8 extends Applet{

  private Label label;                      // 레이블

  public void init(){

    setBackground(Color.yellow);           // 배경색을 노란색으로 정한다.

    label=new Label("안녕");               // 레이블 객체를 만들고 추가한다.

    add(label);

  }

  public void moveLabel(int x, int y){     // 레이블의 위치를 (x, y)로 이동한다.

    label.setLocation(x, y);

  }

}


 

다음으로 Applet8_Controller 클래스를 정의하자.

 

Applet8_Controller.java

 

import java.awt.*;

import java.applet.*;

import java.awt.event.*;

public class Applet8_Controller extends Applet implements MouseMotionListener{

  Applet8 applet8;              // 같은 웹 페이지의 애플릿을 참조하기 위한 변수

  public void init(){

    addMouseMotionListener(this);        // 마우스 이벤트 처리

    setBackground(Color.red);            // 배경색을 빨간 색으로 정한다.

  }

 

  // 마우스가 애플릿 안에서 움직일 때 호출된다.

  public void mouseMoved(MouseEvent me){

    if(applet8==null){                       // applet8이 참조하는 객체가 없으면

       // Applet8을 참조하게 한다.

       applet8=(Applet8)getAppletContext().getApplet("applet8");

    }

    // Applet8 객체의 moveLabel 메소드를 호출한다.

    applet8.moveLabel(me.getX(), me.getY());

  }

  public void mouseDragged(MouseEvent me){}

}


 

아래는 두 애플릿을 포함하는 웹 페이지의 HTML 소스이다.

 

Applet8.htm

 

<Htm>

<Body>

   <Center>

   <Applet code="Applet8.class" name="applet8" width=200 height=200 >

   </Applet>

   <Applet code="Applet8_Controller.class" width=200 height=200 >

   </Applet>

   </Center>

</Body>

</Htm>


 

웹 브라우저로 Applet8.htm을 불러와 보자. 아래 그림처럼 Applet8_Controller에서 마우스를 움직이면 Applet8의 label이 따라서 움직일 것이다.

[그림 19-7] 다른 애플릿 제어하기

 

 

애플릿과 보안

사 용자가 애플릿이 포함된 웹 페이지를 방문하면 원하든 원하지 않든 애플릿이 다운로드 되어 실행된다. 프로그래머가 악의를 품고 사용자측 컴퓨터의 중요한 파일을 지우거나 정보를 빼돌리는 애플릿을 제작했다고 생각해보자. 끔찍한 일이 발생할 것이다. 하지만 다행히도 애플릿은 그와 같은 행위를 할 수 없도록 보안이 확실하다. 보안 사항을 위배하는 코드가 발견되면 애플릿은 보안과 관련된 예외를 던지고 실행을 멈추게 된다.

 

애플릿은 다음과 같은 보안 사항을 가지고 있다.

 

◎ 사용자측 컴퓨터에 설치된 프로그램을 실행시킬 수 없다.

◎ 사용자측 컴퓨터에 있는 파일에 접근할 수 없다.

◎ 사용자측 컴퓨터에 대한 대부분의 정보를 얻을 수 없다.

◎ 사용자측 컴퓨터에 있는 native method를 호출할 수 없다.

◎ applet을 제공하는 서버이외의 다른 컴퓨터와 통신할 수 없다.

 

다음은 애플릿에서 사용자측 컴퓨터에 있는 어떤 파일에 접근했을 때 어떤 것이 발생하는지 알아보는 예제이다.

 

Applet9.java

 

import java.awt.*;

import java.applet.*;

import java.io.*;

public class Applet9 extends Applet{

  TextArea ta=new TextArea("", 10, 30, 1);     // 수직 스크롤 바를 가진 TextArea

  public void init(){

    add(ta);

    File f=new File("c:\\abc.txt");            // 파일 객체 생성

    try{

      if(f.exists())                            // x1

        ta.setText("파일이 있습니다.");

      else

        ta.setText("파일이 없습니다.");

    }

    catch(Exception e){

      ta.setText(e.toString());               // 예외 출력

    }

  }

}


 

아 래 그림은 애플릿 뷰어로 실행된 화면을 캡쳐한 것이다. x1행에서 f.exists()를 호출했을 때 AccessControlException이 발생했음을 알 수 있다. 이 예외는 SecurityException(보안 예외)을 상속한다.

[그림 19-8] 애플릿의 보안

 

 

자 바의 보안은 사용자 입장에서는 좋은 것이지만 프로그래머 입장에서는 많은 부분을 포기하게 만드는 얄미운 것이다. 하지만 무조건 보안 사항이 적용되는 것은 아니다. 브라우저마다 애플릿의 보안을 피할 수 있는 서명 방법이 있다. 그러나 서명 방법은 브라우저마다 달라서 바람직한 방법이 아니다.

 

애플릿은 서버이외의 다른 시스템에 접속할 수 없지만 서버는 다른 시스템에 접속할 수 있다는 점을 이용하면 간접적으로 다른 시스템에 연결할 수 있다.

 

[그림 19-9] 중계 서버

 

 

네트워크 프로그래밍 장에서 구현해 보자.

 

 

교육용 애플릿 만들기

요 즘 들어 교육 소프트웨어가 인터넷용으로 많이 만들어지고 있다. 자바는 다른 도구에 비해 배우기 어려운 것은 사실이지만 표현력이 매우 뛰어나기 때문에 다른 도구가 할 수 없는 부분도 구현할 수 있다. 교육용 애플릿 만들기는 교육용 애플릿에 관심은 있지만 어떻게 구현해야할 지 잘 모르는 초·중·고 선생님들에게 도움이 될 수 있을 것이다.

 

 

물체의 연직 운동

수직으로 물체를 속도 v로 던졌을 때, 시간 t초 후의 물체의 위치 s는 다음과 같다.

 

 

 ,   ( v=처음 속도, g=중력가속도, t=시간 )

 

중 학교 또는 고등학교 시절에 배운 내용이므로 잘 생각해보면 기억날 것이다. 아무튼 애플릿을 실행했을 때 아래와 같은 화면이 보일 것이다. 스크롤 바는 처음 속도의 크기를 조절하기 위한 것으로 오른쪽으로 이동하면 속도가 커진다. 속도를 조절한 후 발사 버튼을 누르면 빨간 공이 수직으로 던져진다. 이때 빨간 공은 시간에 따라 연직 운동 방정식으로 계산된 위치로 움직인다.

[그림 19-10] 물체의 연직 운동

 

다음은 물체의 연직 운동을 구현한 애플릿 예제이다. 코드의 복잡성을 피하기 위해 많은 부분을 생략하였기 때문에 그다지 효율적이지는 못하므로 부족한 부분은 독자가 수정하거나 추가해 보길 바란다.

 

Applet10.java

 

import java.awt.*;

import java.applet.*;

import java.awt.event.*;

public class Applet10 extends Applet implements Runnable, ActionListener{

  private Image imgBall, buff;        // 빨간 공 이미지와 더블 버퍼링을 위한 버퍼

  private Scrollbar vCon;              // 공의 처음 속도 조절을 위한 스크롤 바

  private Thread ballThread;          // 공을 움직이게 하는 스레드

  private double S, V, T;             // S=공의 수직 위치, V=처음 속도, T= 시간

  private static final double G=9.8;    // 중력 가속도

  private Graphics2D ga, gb;         // 애플릿과 버퍼의 Graphics 객체

  private int width,height;                   // 애플릿의 너비와 높이를 위한 변수

  private Button b=new Button("발사");      // 발사 버튼

  private Paint skyPaint=                    // 하늘을 표현하기 위한 Paint 객체

              new GradientPaint(0,0, Color.white, 0, -500, Color.blue, false);

  public void init(){

    width=getWidth();           // 애플릿의 너비를 얻는다.

    height=getHeight();         // 애플릿의 높이를 얻는다.

 

    // 빨간 공 이미지를 얻는다.

    imgBall=getImage(getDocumentBase(),"images/Red_Ball.gif");

   

    getToolkit().prepareImage(imgBall,-1,-1,this);     // 이미지를 준비시킨다.

    buff=createImage(width,height);       // 애플릿과 같은 크기의 버퍼를 만든다.

 

    // 속도 조절을 위한 스크롤 바 객체를 만든다. 처음 속도=50

    vCon=new Scrollbar(Scrollbar.HORIZONTAL,50,1,0,100);

 

    // 컴포넌트를 배치한다.

    setLayout(new BorderLayout());

    Panel p=new Panel();

    p.setLayout(new BorderLayout());

    p.add(vCon,"North");

    p.add(b,"Center");

    add(p,"South");

 

    b.addActionListener(this);           // 액션 이벤트 리스너를 등록한다.

  }

  public void paint(Graphics g){

      if(ga==null)

        ga=(Graphics2D)getGraphics();       // 애플릿의 그래픽 객체를 얻는다.

      if(gb==null){

        gb=(Graphics2D)buff.getGraphics();    // 버퍼의 그래픽 객체를 얻는다.

        gb.translate(width/2, height/2);       // 버퍼의 원점을 버퍼의 가운데로 옮긴다.

      }

      drawScreen();                          // 화면을 그린다.

    }

    // 발사 버튼을 누르면 호출되는 메소드

    public void actionPerformed(ActionEvent ae){

    if(ballThread==null || !ballThread.isAlive()){     // 스레드가 null이거나 죽었으면

      S=0; V=vCon.getValue(); T=0;               // 변수들을 초기화시킨다.

      ballThread=new Thread(this);                // 스레드를 생성한다.

      ballThread.start();                           // 스레드를 실행시킨다.

    }

  }

  public void drawScreen(){                     // 화면을 그리는 메소드

    // 버퍼에 그리기 작업을 한 후 버퍼의 이미지를 애플릿에 그린다.

    gb.setPaint(new Color(200,200,50));       // 버퍼의 지면을 표현하기 위한 Paint

    gb.fillRect(-width/2, 0,width , height/2);             // 지면을 그린다.

    gb.setPaint(skyPaint);                               // 하늘 효과를 위한 Paint

    gb.fillRect(-width/2, -height/2,width , height/2);     // 하늘을 그린다.

    gb.drawImage(imgBall,0,-(int)S,null);                // 공을 (0, -S)에 그린다.

    gb.drawString("T= "+String.valueOf(T),-100,50);     // 시간을 화면에 보여준다.

    gb.drawString("S= "+String.valueOf(S),-100,65);     // 공의 위치를 보여준다.

 

    ga.drawImage(buff,0,0, this);              // 버퍼의 이미지를 애플릿에 그린다.

  }

  public void run(){

    while(true){

      T+=0.1;             // 시간을 0.1초 증가시킨다(실제 시간과는 차이가 있다.)

      S=V*T-0.5*G*T*T;          // 공의 위치를 계산한다.

      drawScreen();               // 화면을 그린다.

      if((int)S<=0)break;          // S가 0보다 작거나 같으면 스레드를 멈춘다.

      try{

        Thread.sleep(100);         // 0.1초간 대기한다.

      }catch(Exception e){}

    }

  }

}


 

   <Applet code="Applet10.class" width=300 height=400 >

   </Applet>

 

 

다양한 모양의 삼각형 작도

그 림 [19-10]과 같은 애플릿을 제작해 보자. 삼각형의 각 꼭지점에 빨간 색의 작은 사각형이 보일 것이다. 이것을 마우스로 끌면 마우스를 따라 움직이면서 삼각형의 모양이 바뀐다.  세 개의 작은 사각형을 조절점이라고 부르자. 그려질 삼각형은 GeneralPath로 구현하며 조절점은 Rectangle2D로 구현할 것이다. 조절점이 세 개이므로 세 개의 Rectangle2D 객체가 필요하다.

[그림 19-11] 삼각형 만들기

 

마우스를 눌렀을 때 선택된 조절점을 찾기 위해서 Rectangle2D.Double의 contains 메소드를 사용할 것이다. contains 메소드는 주어진 좌표가 도형 안에 있으면 true를 반환한다.

 

Applet11.java

 

import java.awt.*;

import java.applet.*;

import java.awt.event.*;

import java.awt.geom.*;

public class Applet11 extends Applet

                       implements MouseListener, MouseMotionListener{

  Rectangle2D[] p=new Rectangle2D.Double[3];  // 삼각형의 조절점 3개(0~2)

  Image buff;                                       // 버퍼 이미지

  Graphics2D ga, gb;                           // 애플릿과 버퍼의 Graphics 객체

  

  // 마우스로 조절점을 눌렀을 때 마우스 위치와 조절점 위치(x, y)와의 거리

  double dx, dy;

  

  // 마우스로 선택한 조절점의 번호(0~2), 선택하지 않으면 -1이 대입된다.

  int selection=-1;

  public void init(){

    buff=createImage(getWidth(),getHeight());     // 버퍼 객체를 생성한다.

    gb=(Graphics2D)buff.getGraphics();          // 버퍼의 Graphics 객체를 얻는다.

    p[0]=new Rectangle2D.Double(150, 50, 5, 5);   // 조절점 객체를 생성한다.

    p[1]=new Rectangle2D.Double(60, 200, 5, 5);

    p[2]=new Rectangle2D.Double(240, 200, 5, 5);

    addMouseMotionListener(this);           // 마우스 움직임 이벤트를 처리한다.

    addMouseListener(this);                 // 마우스 이벤트를 처리한다.

  }

  public void paint(Graphics g){

    if(ga==null)

      ga=(Graphics2D)getGraphics();       // 애플릿의 Graphics 객체를 얻는다.

    drawScreen();                         // 화면을 그린다.

  }

  public void drawScreen(){                     // 화면을 그리는 메소드

    gb.clearRect(0, 0, getWidth(), getHeight());   // 버퍼 이미지를 지운다.

    GeneralPath triangle =new GeneralPath();    // 삼각형을 표현하는 객체

 

    // 삼각형의 각 꼭지점의 좌표를 정하고 선을 긋는다.

    triangle.moveTo((float)p[0].getX(), (float)p[0].getY());

    triangle.lineTo((float)p[1].getX(), (float)p[1].getY());

    triangle.lineTo((float)p[2].getX(), (float)p[2].getY());

    triangle.closePath();  // 삼각형의 경로를 닫는다.

 

    // 버퍼에 그리기 작업을 한다.

    gb.setPaint(new Color(204, 205, 255));     // 주어진 색상으로 삼각형을 채운다.

    gb.fill(triangle);

    gb.setPaint(new Color(0, 0, 0));      // 검정색으로 삼각형의 외각선을 그린다.

    gb.draw(triangle);

 

    gb.setPaint(Color.red);          // 빨간 색 Paint를 설정한다.

    for(int i=0;i<p.length;i++)        // 각 조절점을 채우기로 그린다.

      gb.fill(p[i]);

    

    ga.drawImage(buff, 0, 0, this);        // 버퍼의 이미지를 애플릿에 그린다.

  }

  public void mousePressed(MouseEvent me){  // 마우스를 누러면 호출된다.

    int mx=me.getX(), my=me.getY();            // 마우스의 좌표를 얻는다.

 

    // 마우스에 의해 눌러진 조절점을 찾는다.

    for(int i=0;i<p.length;i++)

      if(p[i].contains(mx, my)){        // 마우스 좌표가 i번째의 조절점 안에 있으면

        // 마우스 좌표와 조절점 좌표의 거리를 계산한다.

        dx=mx-(int)p[i].getX();

        dy=my-(int)p[i].getY();

 

        selection=i;                        // 선택한 조절점의 번호를 기억한다.

        break;

      }

  }

  public void mouseDragged(MouseEvent me){      // 마우스를 끌면 호출된다.

    if(selection>=0 && selection <=p.length){      // 선택한 조절점이 있으면(0~2)

      int mx=me.getX(), my=me.getY();              // 마우스의 좌표를 얻는다.

      p[selection].setFrame(mx-dx, my-dy, 5, 5);    // 조절점의 좌표를 이동한다.

      drawScreen();                                 // 화면을 그린다.

    }

  }

  public void mouseReleased(MouseEvent me){    // 누른 버튼을 놓으면 호출된다.

    selection=-1;                                // 조절점을 선택하지 않는다.

  }

  public void mouseMoved(MouseEvent me){}

  public void mouseEntered(MouseEvent me){}

  public void mouseExited(MouseEvent me){}

  public void mouseClicked(MouseEvent me){}

}


 

<Applet code="Applet11.class" width=300 height=300 >

</Applet>

 

 

 

 

연습 문제

 

 

1. 육각형의 꼭지점을 마우스로 끌면 육각형의 크기가 변하는 애플릿을 제작해보자. 단, 마주보는 꼭지점과 연결된 직선 방향으로만 움직이게 해야한다.

 

[그림 19-12] 육각형 작도

 

 

2. 빨간 점을 중심으로 회전하는 물체를 보여주는 애플릿을 제작해보자. 속도를 조절할 수 있는 버튼도 만들어보자.

 

[그림 19-13] 원심력

 

 

3. 도르래의 원리를 보여주는 애플릿을 제작해보자. 그림과 같이 도르래에 매달린 물체를 아래 또는 위로 당기면 물체가 움직이도록 해보자. 반대쪽의 물체는 역 방향으로 움직인다.

 

[그림 19 14] 도르래

[출처] 애플릿 Applet|작성자 원준아빠


[본문링크] 애플릿 Applet
탭으로 나뉘어져 있는 글입니다.   [1][2][3][4][5][6][7][8][9]
코멘트(이글의 트랙백 주소:/cafe/tb_receive.php?no=2863
작성자
비밀번호

 

SSISOCommunity
탭글
[1][2][3]
[4][5][6]
[7][8][9]

[이전]

Copyright byCopyright ⓒ2005, SSISO Community All Rights Reserved.